﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using MVVMGrid.UsingReactive.Models;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.ComponentModel.Composition;
using System.Collections.Generic;
using System.Concurrency;

namespace MVVMGrid.UsingReactive.Services
{
    [Export]
    public class GridService
    {
        private const string ListFileName = "/Data/Settings.xml";
        private readonly Uri WebSiteUri = HtmlPage.Document.DocumentUri;

        public IObservable<ViewSettingsCollection> GetViewSettingsCollection()
        {
            Uri listFileUri = new Uri( WebSiteUri, ListFileName );
            WebRequest httpReq = HttpWebRequest.Create( listFileUri );
            return
                Observable
                    .FromAsyncPattern<WebResponse>( httpReq.BeginGetResponse, httpReq.EndGetResponse )()
                    .Select( r =>
                    {

                        XDocument rspDoc;
                        using( Stream rspStream = r.GetResponseStream() )
                            rspDoc = XDocument.Load( rspStream );

                        return
                            rspDoc
                                .Element( "settings" )
                                .Elements( "items" )
                                .Select( items =>
                                    new ViewSettingsCollection {
                                        DefaultViewSettingsID = (int?)items.Attribute( "default" ),
                                        Items = new List<ViewSettingsCollectionItem>(
                                            items
                                                .Elements( "item" )
                                                .Select( item => new ViewSettingsCollectionItem {
                                                    ID = (int)item.Attribute( "id" ),
                                                    Description = (string)item.Attribute( "desc" ),
                                                    Link = (string)item.Attribute( "link" )
                                                })
                                        )
                                })
                                .Single();

                    } );
        }

        public IObservable<ViewSettings> GetViewSettings( ViewSettingsCollectionItem item )
        {
            Uri listFileUri = new Uri( WebSiteUri, ListFileName );
            Uri itemFileUri = new Uri( listFileUri, item.Link );
            WebRequest httpReq = HttpWebRequest.Create( itemFileUri );
            return
                Observable
                    .FromAsyncPattern<WebResponse>( httpReq.BeginGetResponse, httpReq.EndGetResponse )()
                    .Select( r =>
                    {
                        XDocument rspDoc;
                        using( Stream rspStream = r.GetResponseStream() )
                            rspDoc = XDocument.Load( rspStream );

                        return
                            rspDoc
                                .Elements( "viewSettings" )
                                .Select( settings =>
                                    new ViewSettings
                                    {
                                        Description = (string)settings.Element( "desc" ),
                                        Columns = new List<ViewColumnSettings>(
                                            settings
                                                .Element( "columns" )
                                                .Elements( "column" )
                                                .Select( column => new ViewColumnSettings {
                                                    ColumnID = (string)column.Attribute( "id" ),
                                                    ColumnWidth = (int)column.Attribute( "width" )
                                                })
                                        )
                                    }
                                )
                                .Single();
                    } );
        }

        public IObservable<GridDataCollection> GetGridItems()
        {
            return
                Observable
                    .Repeat( 0, 1 )
                    .Select( _ =>
                    {
                        GridDataCollection gridDataCollection = new GridDataCollection();
                        gridDataCollection.AddRandomData( 100 );
                        return gridDataCollection;
                    } )
                    .SubscribeOn( Scheduler.ThreadPool );
        }
    }
}
